#ifndef CIPODIAP1_H_
#define CIPODIAP1_H_

#include <semaphore.h>
#include "Iap1Def.h"
#include "CIpodProtocol.h"

#ifdef __cplusplus
extern "C"{
#endif

#define BITMAP_MAX_SIZE      224800

class CIpodIap1 : public CIpodProtocol {
public:
    CIpodIap1();
    ~CIpodIap1();

private:
    int init(int connMode);
    int deinit();
    int packetProc(const uint8 *data, uint16 len, bool native);

    /************************************************************************************
     * Variables
     ************************************************************************************/
    bool                        m_TransIDSupport;
    uint16                      m_GlobalTransID;
    sem_t                       m_WaitSem;
    pthread_mutex_t             m_WaitMutex;
    std::list<RECEIVE_DATA_S>   m_RecvDatas;
    bool                        m_ReponseGetAccessoryInfo;
    uint8                       m_AuthSignature[20];
    uint8                       m_SignatureData[128];
    bool                        m_A2dpConnected;
    pthread_mutex_t             m_ProctectMutex;
    ArtworkData                 m_ArtworkData;
    uint32                      m_BitmapPoint;
    uint8                       m_BitmapData[BITMAP_MAX_SIZE];
    char                        m_ArtworkPath[1024];
    int                         m_CurrentCategoryType;
    int                         m_NextCategoryType;
    int                         m_CategoryTypeQueue[5];
    int                         m_CategoryTypeIndex;
    bool                        m_DBReset;
    bool                        m_SupportAllCategory;
    pthread_mutex_t             m_ListMutex;
    IAP_OPTIONS_FOR_LINGO       m_OptionsForLingo[16];

    /************************************************************************************
     * Interface
     ************************************************************************************/
    int notifyBtStatus(bool connected);
    int notifyUSBAudioStatus(bool enabled);
    int sendMediaCommand(int command);
    int sendMediaCommandDown(int command);
    int sendMediaCommandUp(int command);
    int setPlayingTrackPosition(uint32 position);
    int getShuffleMode(int *mode);
    int getRepeatMode(int *mode);
    int getPlayingTrackDuration(int * duration);
    int getPlayingTrackTitle(std::string &title);
    int getPlayingTrackAlbum(std::string &album);
    int getPlayingTrackArtist(std::string &artist);
    int getPlayingTrackAlbumArtwork();
    int getPlayStatus(IPODPlayStatus *status);
    int getPlayingTrackInfo(int32 *index, uint32 *count);
    int getPlayingChapterInfo(int32 *index, uint32 *count);
    int isListLevelSupported(bool *supported);
    int resetMusicList(uint32 *num);
    int selectMusicList(int32 index, int32 level, uint32 *num);
    int selectMusicPlayingList(int32 index);
    int getMusicList(uint32 startIndex, uint32 readCount, IPODMusicList *musicList);
    int getMusicList_c(uint32 startIndex, uint32 readCount, C_IPODMusicList *musicList);
    int getMusicPlayingList(uint32 startIndex, uint32 readCount, C_IPODMusicList *musicList);
    int launchApp(const char *appBundleID);
    int sendEAData(const uint8 *data, uint16 len);
	int getDeviceInformation();
    int setLocationInformation(const char *sentence);
    int carPlayStartSession(int type);
    int oOBBTPairingCompletionInformation(int resultCode );
    int bluetoothPairingAccessoryInformation(const char * inPairingDataP192,const char * inPairingDataP256);
    int bluetoothPairingStatus( int success, const char * cancelReason);

    /************************************************************************************
     * Packet
     ************************************************************************************/
    uint16 createIapPacket(uint8 lingoID, uint16 commandID, uint16 transID, const uint8 *buf, uint16 len, uint8 *desbuf);
    uint16 createFIDTokenIdentifyPacket(uint8 numLingoes, const uint8 *accessoryLingoes, uint32 deviceOption, uint32 deviceID, uint8 *desbuf);
    uint16 createFIDTokenAccessoryCapsPacket(const uint8 *accCapsBitmask, uint8 *desbuf);
    uint16 createFIDTokenAccessoryInfoPacket(uint8 accInfoType, uint8 accInfoLen, const char *accInfo, uint8 *desbuf);
    uint16 createAccessoryAckPacket(uint8 lingoID, uint16 transID, uint8 commandStatus, uint8 respondID, uint8 *desbuf);
    uint8 getAckID(uint8 lingoID);
    bool isAckPacket(uint8 lingoID, uint8 command);
    void postWaitSem(uint8 lingoID, uint16 commandID, uint16 transID, uint16 len, const uint8 *data);
    void fillWaitPacket(uint8 lingoID, uint16 commandIDd, uint16 transID, uint16 len, const uint8 *data);
    int getResponseData(RECEIVE_DATA_S *recvData);
    int waitResponse(uint32 timeout);
    int waitAck(int timeout, uint8 lingo, uint16 trans, RECEIVE_DATA_S *recvData);
    int waitCommand(int timeout, uint8 lingoID, uint16 commandID, uint16 transID, RECEIVE_DATA_S *recvData);

    /************************************************************************************
     * Command
     ************************************************************************************/
    int startIDPS(uint8 *ack);
    int endIDPS();
    int requestTransportMaxPayloadSize();
    int getOptionForLingo(IPOD_LINGOS lingoID, IAP_OPTIONS_FOR_LINGO *option);
    int setFIDTokenValues();
    int identifyDeviceLingoes(uint32 lingoesSpoken, uint32 option, uint32 deviceID, uint32 optionFlag);
    int retAccessoryAuthInfo(uint16 transID);
    int retAccessoryAuthSignature(uint16 transID);
    int setParam();
    int getSupportedEventNotification(uint64 *data);
    int setEventNotification(uint64 data);
    int setAvailableCurrent(uint16 current);
    int setUIMode(IPODUIMode uiMode);
    int enterExtendedInterfaceMode();
    int requestExtendedInterfaceMode();
    int setPlayStatusChangedNotification(uint32 changeEvent);
    int setRemoteEventNotification(uint32 changeEvent);
    int ackAuthInfo(uint16 transID);
    int retAccessoryInfo(uint8 infoType);
    int retAccessoryStatusNotification(uint16 transID);
    int accessoryStatusNotification(bool connected);
    int retAccessorySampleRate(uint16 transID);
    int generalLingoAccessoryAck(uint8 lingoID, uint16 transID, uint8 ackStatus, uint8 ackCommandID);
    int dealWithStatusChangeNotification(const uint8 *data);
    int dealWithDisplayRemoteEventNotification(const uint8 *data);
    int setPlayStatus(int command);
    int setShuffleMode();
    int setRepeatMode();
    int displayRemoteSetStateInfo(IPOD_DR_STATUS_INFO statusInfo, const uint8 *infoData, uint16 dataLen);
    int getCurrentPlayingTrackIndex(int32 *index);
    int getIndexedPlayingTrackTitle(uint32 index, std::string &title);
    int getIndexedPlayingTrackAlbum(uint32 index, std::string &album);
    int getIndexedPlayingTrackArtist(uint32 index, std::string &artist);
    int getArtworkFormats(pArtworkFormat artworkFormat, uint32 *formatLen);
    int getTrackArtworkData(uint16 formatID, uint32 index);
    int getNumberPlayingTracks(uint32 *count);
    int resetDBSection();
    int getNumberCategorizedDBRecords(uint32 *recordNum, int type);
    int selectDBRecord(int type, int32 index);
    int retrieveCategorizedDBRecords(int type, uint32 startIndex, uint32 count, std::list<IPODMusicSource> &sourceList);
    int retrieveCategorizedDBRecords_c(int type, uint32 startIndex, uint32 count, C_IPODMusicSource *sourceList);

};
#ifdef __cplusplus
}
#endif
#endif /* CIPODIAP1_H_ */
